﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography.X509Certificates;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using Sistema.Dominio;

namespace Sistema.Util
{
    public class CertificadoDigital
    {
        /// <summary>
        /// Metodo que invoca a API do windows, nela sera chamada a tela de seleção de certificados digitais do windows, 
        /// o retorno sera uma classe X509Certificate2 caso o usuario tenha escolhido um certidicado ou null caso ele tenha cancelado a operação. 
        /// </summary>
        /// <param name="Titulo">Titulo da tela de seleção de certificado.</param>
        /// <param name="Mensagem">Mensagem de corpo da tela de selecao de certificado.</param>
        /// <returns>Uma classe x509certificate2 instanciada com os dados do certificado pesquisado ou uma null caso a operação foi cancelada.</returns>
        /// <exception cref="Sistema.Util.UtilException">Erro lancado sob qualqer erro envolvendo esta busca.</exception>
        public X509Certificate2 PesquisarCertificadoDigital(String Titulo = "teste", String Mensagem ="MensagemTeste")
        {
            X509Certificate2 retorno = null;
            try
            {
                X509Certificate2Collection collection = X509Certificate2UI.SelectFromCollection(this.ListarCertificadosDigitais(), "Cerificado Digital", "Selecione o Cerificado Digital de Sua Empresa", X509SelectionFlag.SingleSelection);
                if (collection.Count == 0) { }
                else {  retorno = collection[0]; }
               
            }
            catch
            {

            }
            return retorno;
        }
        public X509Certificate2Collection ListarCertificadosDigitais()
        {
            StorePermission sp = new StorePermission(StorePermissionFlags.AllFlags);

            X509Store store = new X509Store(StoreName.My,StoreLocation.CurrentUser);
            
            store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
            X509Certificate2Collection collection = store.Certificates;
            X509Certificate2Collection collection1 = collection.Find(X509FindType.FindByTimeValid, DateTime.Now, true);
            X509Certificate2Collection collection2 = collection1.Find(X509FindType.FindByKeyUsage, X509KeyUsageFlags.DigitalSignature, true);//.FindByKeyUsage
            store.Close();
            return collection;// busca por todos os certificados digitais da máquina do usuário, sem filtros.
        }
         public void ExibirDadosCetificado()
        {
            X509Certificate certificado = this.PesquisarCertificadoDigital();

            
        }

         public CertificadoVO IdentificarCertificado(X509Certificate2 certificado)
         {
             try
             {
                 CertificadoVO certVO = new CertificadoVO();
                 X509Certificate2 _X509Cert = certificado;
                 String sName = Convert.ToString(_X509Cert.Issuer);
                 String sSubject = _X509Cert.Subject;
                 DateTime dValidadeInicial = _X509Cert.NotBefore.Date;
                 DateTime dValidadeFinal = _X509Cert.NotAfter.Date;

                 DateTime hora;
                 DateTime horaAfter;
                 DateTime hoje;
                 hoje = DateTime.Today;

                 String[] resultados;
                 String[] cnpj;
                 String[] nome;
                 String[] tipo;
                 String[] certificador;
                 String[] cidade;

                 String _nome;
                 String _cnpj;
                 String _cidade;
                 String _tipo;
                 String _certificador;


                 if (sSubject.StartsWith("CN"))
                 {
                     resultados = certificado.Subject.Split(',');
                     cnpj = resultados[0].Split(':');
                     nome = cnpj[0].Split('=');
                     tipo = resultados[2].Split(' ');
                     certificador = resultados[1].Split('=');
                     cidade = resultados.Last().Split('=');

                     _nome = nome[1].ToString();
                     _cnpj = cnpj[1].ToString();
                     _cidade = cidade[1].ToString();
                     _tipo = tipo[3].ToString();
                     _certificador = certificador[1].ToString();
                 }
                 else
                 {
                     resultados = certificado.Subject.Split(',');
                     nome = resultados[1].Split('=');
                     tipo = resultados[4].Split(' ');
                     certificador = resultados[5].Split('=');

                     _nome = nome[1].ToString();
                     _cnpj = "00.000.000/0000-00";
                     _cidade = "Não Identificado";
                     _tipo = tipo[3].ToString();
                     _certificador = certificador[1].ToString();
                 }


                 hora = certificado.NotBefore;
                 horaAfter = certificado.NotAfter;

                 certVO.Certificado = sSubject;
                 certVO.Expiracao = Convert.ToString(dValidadeFinal.ToShortDateString());
                 certVO.DataInicial = Convert.ToString(dValidadeInicial.ToShortDateString());
                 certVO.Nome = _nome;
                 certVO.CNPJ = _cnpj;
                 certVO.Cidade = _cidade;
                 certVO.Tipo = _tipo;
                 certVO.Certificador = _certificador;
                 certVO.Hora = hora.ToShortTimeString();
                 certVO.HoraFinal = horaAfter.ToShortTimeString();

                 return certVO;
             }
             catch (Exception)
             {
                 throw;
             }
         }
    }
}
